package at.fhhagenberg.hydrac.java.sample.ast.codegen.builder;

import java.util.List;

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;

public class MethodBuilder {

	private final AST ast;

	private final MethodDeclaration methodDecl;

	public MethodBuilder(ClassBuilder classBuilder, String name) {
		this.ast = classBuilder.getAst();
		// --
		methodDecl = ast.newMethodDeclaration();
		methodDecl.setName(ast.newSimpleName(name));
		methodDecl.setBody(ast.newBlock());
		// --
		classBuilder.addMethodDecleration(methodDecl);
	}

	public MethodBuilder defineAsConstructure() {
		methodDecl.setConstructor(true);
		return this;
	}

	public MethodBuilder addModifier(ModifierKeyword modifier) {
		List modifiers = methodDecl.modifiers();
		modifiers.add(ast.newModifier(modifier));
		return this;
	}

	public MethodBuilder setReturnType(PrimitiveType.Code type) {
		methodDecl.setReturnType2(ast.newPrimitiveType(type));
		return this;
	}

	public MethodBuilder addParameterDeclaration(String name, Type type) {
		SingleVariableDeclaration varDecl = ast.newSingleVariableDeclaration();
		varDecl.setType(type);
		varDecl.setName(ast.newSimpleName(name));
		methodDecl.parameters().add(varDecl);
		return this;
	}

	public MethodBuilder addStatement(Statement stmt) {
		methodDecl.getBody().statements().add(stmt);
		return this;
	}

	public MethodBuilder addVariableDeclaration(String name, Type type, Expression initializer) {
		VariableDeclarationFragment varDecl = ast.newVariableDeclarationFragment();
		varDecl.setName(ast.newSimpleName(name));
		varDecl.setExtraDimensions(0);
		varDecl.setInitializer(initializer);

		VariableDeclarationStatement varDecltStmt = ast.newVariableDeclarationStatement(varDecl);
		varDecltStmt.setType(type);

		addStatement(varDecltStmt);
		return this;
	}

}
